/*
 * p2196.cpp
 *
 *求树的点到其他点的最长距离：
 *len[u][i]:u到其第i个儿子的距离
 *dp[u][0]:u到其子树中的点的最长距离
 *  dp[u][1]：u到其子树中的点的次长距离（不来自最长距离的子树）
 *  g【u】:u通过父节点到树中其他点的最长距离

ans=max（g【u】，dp【u】【0】）
 */

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 10010;
int dp[maxn][2], g[maxn];
int n;
vector<int> son[maxn], len[maxn];
void dfs(int u)
{
	int lid;//最长距离来自的子树id
	//求最长距离
	for (int i = 0; i < son[u].size(); i++)
	{
		int v = son[u][i];
		dfs(v);
		int ll = dp[v][0] + len[u][i];
		if (ll > dp[u][0])
		{
			dp[u][0] = ll;
			lid = v;
		}
	}
	//求次长距离
	for (int i = 0; i < son[u].size(); i++)
	{
		int v = son[u][i];
		int ll = dp[v][0] + len[u][i];
		if (v != lid && ll > dp[u][1]) dp[u][1] = ll;
	}
}
void dfs2(int u)
{
	for (int i = 0; i < son[u].size(); i++)
	{
		int v = son[u][i];
		if (dp[v][0] + len[u][i] != dp[u][0])
			g[v] = max(g[u], dp[u][0]) + len[u][i];
		else
			g[v] = max(g[u], dp[u][1]) + len[u][i];
		dfs2(v);
	}
}
int main()
{
	while (scanf("%d", &n) != EOF)
	{
		memset(dp, 0, sizeof(dp));
		memset(g, 0, sizeof(g));
		for (int i = 1; i <= n; i++)
		{
			son[i].clear();
			len[i].clear();
		}
		for (int i = 2; i <= n; i++)
		{
			int a, b;
			scanf("%d%d", &a, &b);
			son[a].push_back(i);
			len[a].push_back(b);
		}
		dfs(1);
		dfs2(1);
		for (int i = 1; i <= n; i++)
			printf("%d\n", max(g[i], dp[i][0]));
	}
	return 0;
}
